package com.minelx.landisk.filesystem.core.provider;

import com.minelx.landisk.filesystem.core.Directory;
import com.minelx.landisk.filesystem.core.File;
import com.minelx.landisk.filesystem.core.Locator;
import com.minelx.landisk.filesystem.core.Path;
import com.minelx.landisk.filesystem.core.init.OpenPolicy;
import com.minelx.landisk.filesystem.core.values.PathDescription;
import com.minelx.landisk.filesystem.core.values.SchemeAndAuthority;
import com.minelx.landisk.filesystem.core.values.URI;

import java.util.Map;
import java.util.NoSuchElementException;

public class FSRegister {

	private final Map<SchemeAndAuthority, FS> registry;

	private FSRegister(Map<SchemeAndAuthority, FS> registry) {
		this.registry = registry;
	}

	public Path path(String uriAsText) {
		URI uri = URI.from(uriAsText);
		return determine(uri.schemeAndAuthority()).path(uri.path());
	}

	public File file(String uriAsText, OpenPolicy openPolicy) {
		URI uri = URI.from(uriAsText);
		return determine(uri.schemeAndAuthority()).file(uri.path(), openPolicy);
	}

	public Directory dir(String uriAsText, OpenPolicy openPolicy) {
		URI uri = URI.from(uriAsText);
		return determine(uri.schemeAndAuthority()).dir(uri.path(), openPolicy);
	}

	public Locator determine(SchemeAndAuthority schemeAndAuthority) {
		FS fs = registry.entrySet().stream()
				.filter(which -> which.getKey().equals(schemeAndAuthority))
				.map(Map.Entry::getValue)
				.findFirst().orElseThrow(() -> new NoSuchElementException("no scheme&authority: " + schemeAndAuthority.toText()));
		return new Locator(fs, PathDescription.root());
	}

	public static FSRegister create(Map<SchemeAndAuthority, FS> registry) {
		return new FSRegister(registry);
	}
}
